import type { TablePaginationConfig, ListProps } from "ant-design-vue";
import { ComputedRef, onMounted, Ref, ref, UnwrapRef, watch } from "vue";
import type { PaginationParam, SearchModel, TableRecord } from "/@/api/models";
import { usePagination, UsePaginationOptions } from "/@/hooks/usePagination";
import CURD, { CURDApiOptions } from "/@/api/curd";

export interface CURDOptions<T> extends CURDApiOptions {
  //是否在onMounted中执行一次reloadTable
  loadOnMounted?: boolean;
  onLoadSuccess?: UsePaginationOptions<T>["onLoadSuccess"];
  onLoadError?: (err?: any) => void;
  pageSize?: number;
  loadFilter?: UsePaginationOptions<T>["loadFilter"];
  mockData?: any;
}

export function getTrimSearchModel(model?: SearchModel) {
  if (model) {
    model = { ...model };
    for (const i in model) {
      const val = model[i];
      if (val && typeof val === "string") {
        model[i] = val.trim();
      }
    }
  }
  return model;
}

/**
 * 适用于1个表格的增删查改
 */
export function useCURD<T = TableRecord, K = SearchModel>(options: CURDOptions<T>) {
  options = Object.assign(
    {
      loadOnMounted: true,
    },
    options
  );
  let curd: CURD<T, K> = new CURD<T, K>(options);
  let pagination: ComputedRef<TablePaginationConfig> | undefined = undefined,
    tableData: Ref<UnwrapRef<T[]>> = ref([]),
    tableLoading: Ref<boolean> = ref(false),
    reloadTable: (params?: K | PaginationParam<K>) => void = () => {};
  let searchModel: Ref<SearchModel> = ref({});
  if (options.getPageUrl) {
    //分页
    const getPage = curd.getPage.bind(curd);
    const {
      refreshPagination,
      pagination: innerPagination,
      pageData,
      loading,
      searchModel: pageSearchModel,
    } = usePagination<T, K>({
      reqApi: getPage,
      initPageSize: options.pageSize,
      loadFilter: options.loadFilter,
      onLoadSuccess: options.onLoadSuccess,
    });
    tableData = pageData;
    tableLoading = loading;
    reloadTable = refreshPagination;
    pagination = innerPagination;
    searchModel = pageSearchModel;
  } else if (options.getDataUrl) {
    //不分页
    reloadTable = async (params?: K | PaginationParam<K>) => {
      if (params) {
        Object.assign(searchModel.value, params);
      } else if (params === null) {
        searchModel.value = {};
      }
      tableLoading.value = true;
      let data = await curd.getData(getTrimSearchModel(searchModel.value));
      if (!data) {
        options.onLoadError && options.onLoadError();
      }
      tableLoading.value = false;
      if (options.loadFilter) {
        data = options.loadFilter(data);
      }
      if (options.onLoadSuccess) {
        options.onLoadSuccess(data);
      }
      tableData.value = (data || []) as UnwrapRef<T[]>;
    };
  } else if (options.mockData) {
    reloadTable = () => {
      tableLoading.value = true;
      setTimeout(() => {
        tableLoading.value = false;
        tableData.value = options.mockData;
      }, 800);
    };
  }
  if (options.loadOnMounted) {
    onMounted(async () => {
      await reloadTable();
    });
  }
  return {
    pagination,
    tableData,
    tableLoading,
    curd,
    reloadTable,
    searchModel,
  };
}
